{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ridge/LASSO polynomial regression with linear and random sampling\n",
    "* Input variable space is constructed using random sampling/cluster pick/uniform sampling\n",
    "* Linear fit is often inadequate but higher-order polynomial fits often leads to overfitting i.e. learns spurious, flawed relationships between input and output\n",
    "* Ridge and LASSO regression are used with varying model complexity (degree of polynomial)\n",
    "* Model score is obtained on a test set and average score over a # of runs is compared for linear and random sampling"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Import libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "from sklearn.linear_model import LassoCV\n",
    "from sklearn.linear_model import RidgeCV\n",
    "from sklearn.preprocessing import PolynomialFeatures\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.pipeline import make_pipeline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Global variables for the program"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "N_points = 41 # Number of points for constructing function\n",
    "x_min = 1 # Min of the range of x (feature)\n",
    "x_max = 10 # Max of the range of x (feature)\n",
    "noise_mean = 0 # Mean of the Gaussian noise adder\n",
    "noise_sd = 5 # Std.Dev of the Gaussian noise adder\n",
    "ridge_alpha = tuple([10**(x) for x in range(-4,0,1) ]) # Alpha (regularization strength) of ridge regression\n",
    "lasso_eps = 0.001\n",
    "lasso_nalpha=20\n",
    "lasso_iter=2000\n",
    "degree_min = 2\n",
    "degree_max = 8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generate feature and output vector following a non-linear function\n",
    "\n",
    "$$ The\\ ground\\ truth\\ or\\ originating\\ function\\ is\\ as\\ follows:\\  $$\n",
    " \n",
    "$$ y=f(x)= x^2.sin(x).e^{-0.1x}+\\psi(x) $$\n",
    "\n",
    "$$: \\psi(x) = {\\displaystyle f(x\\;|\\;\\mu ,\\sigma ^{2})={\\frac {1}{\\sqrt {2\\pi \\sigma ^{2}}}}\\;e^{-{\\frac {(x-\\mu )^{2}}{2\\sigma ^{2}}}}} $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def func(x):\n",
    "    result = x**2*np.sin(x)*np.exp(-(1/x_max)*x)\n",
    "    return (result)\n",
    "\n",
    "noise_x = np.random.normal(loc=noise_mean,scale=noise_sd,size=N_points)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Run # 1 finished\n",
      "Run # 2 finished\n",
      "Run # 3 finished\n",
      "Run # 4 finished\n",
      "Run # 5 finished\n",
      "Run # 6 finished\n",
      "Run # 7 finished\n",
      "Run # 8 finished\n",
      "Run # 9 finished\n",
      "Run # 10 finished\n",
      "Run # 11 finished\n",
      "Run # 12 finished\n",
      "Run # 13 finished\n",
      "Run # 14 finished\n",
      "Run # 15 finished\n",
      "Run # 16 finished\n",
      "Run # 17 finished\n",
      "Run # 18 finished\n",
      "Run # 19 finished\n",
      "Run # 20 finished\n",
      "Run # 21 finished\n",
      "Run # 22 finished\n",
      "Run # 23 finished\n",
      "Run # 24 finished\n",
      "Run # 25 finished\n",
      "Run # 26 finished\n",
      "Run # 27 finished\n",
      "Run # 28 finished\n",
      "Run # 29 finished\n",
      "Run # 30 finished\n",
      "Run # 31 finished\n",
      "Run # 32 finished\n",
      "Run # 33 finished\n",
      "Run # 34 finished\n",
      "Run # 35 finished\n",
      "Run # 36 finished\n",
      "Run # 37 finished\n",
      "Run # 38 finished\n",
      "Run # 39 finished\n",
      "Run # 40 finished\n",
      "Run # 41 finished\n",
      "Run # 42 finished\n",
      "Run # 43 finished\n",
      "Run # 44 finished\n",
      "Run # 45 finished\n",
      "Run # 46 finished\n",
      "Run # 47 finished\n",
      "Run # 48 finished\n",
      "Run # 49 finished\n",
      "Run # 50 finished\n"
     ]
    }
   ],
   "source": [
    "var_linear =[]\n",
    "var_random =[]\n",
    "mean_linear =[]\n",
    "mean_random =[]\n",
    "dfs = []\n",
    "\n",
    "for i in range(50):\n",
    "    \n",
    "    #x_smooth = np.array(np.linspace(x_min,x_max,1001))\n",
    "    # Linearly spaced sample points\n",
    "    X=np.array(np.linspace(x_min,x_max,N_points))\n",
    "    # Samples drawn from uniform random distribution\n",
    "    X_sample = x_min+np.random.rand(N_points)*(x_max-x_min)\n",
    "    #noise_x = np.random.normal(loc=noise_mean,scale=noise_sd,size=N_points)\n",
    "\n",
    "    y = func(X)+noise_x\n",
    "    y_sampled = func(X_sample)+noise_x\n",
    "\n",
    "    df = pd.DataFrame(data=X,columns=['X'])\n",
    "    df['Ideal y']=df['X'].apply(func)\n",
    "    df['y']=y\n",
    "    df['X_sampled']=X_sample\n",
    "    df['y_sampled']=y_sampled\n",
    "\n",
    "    X_train, X_test, y_train, y_test = train_test_split(df['X'], df['y'], test_size=0.33)\n",
    "    X_train=X_train.values.reshape(-1,1)\n",
    "    X_test=X_test.values.reshape(-1,1)\n",
    "\n",
    "    linear_sample_score = []\n",
    "    poly_degree = []\n",
    "    for degree in range(degree_min,degree_max+1):\n",
    "        model = make_pipeline(PolynomialFeatures(degree), RidgeCV(alphas=ridge_alpha,normalize=True,\n",
    "                                                                  cv=5))\n",
    "        #model = make_pipeline(PolynomialFeatures(degree), LassoCV(eps=lasso_eps,n_alphas=lasso_nalpha, \n",
    "                                                                  #max_iter=lasso_iter,normalize=True,cv=5))\n",
    "        #model = make_pipeline(PolynomialFeatures(degree), LinearRegression(normalize=True))\n",
    "        model.fit(X_train, y_train)\n",
    "        y_pred = np.array(model.predict(X_train))\n",
    "        test_pred = np.array(model.predict(X_test))\n",
    "        RMSE=np.sqrt(np.sum(np.square(y_pred-y_train)))\n",
    "        test_score = model.score(X_test,y_test)\n",
    "        linear_sample_score.append(test_score)\n",
    "        poly_degree.append(degree)\n",
    "    \n",
    "    var_linear.append(np.std(np.array(linear_sample_score)))\n",
    "    mean_linear.append(np.mean(np.array(linear_sample_score)))\n",
    "\n",
    "    # Modeling with randomly sampled data set\n",
    "    X_train, X_test, y_train, y_test = train_test_split(df['X_sampled'], df['y_sampled'], test_size=0.33)\n",
    "    X_train=X_train.values.reshape(-1,1)\n",
    "    X_test=X_test.values.reshape(-1,1)\n",
    "\n",
    "    random_sample_score = []\n",
    "    poly_degree = []\n",
    "    for degree in range(degree_min,degree_max+1):\n",
    "        model = make_pipeline(PolynomialFeatures(degree),RidgeCV(alphas=ridge_alpha,normalize=True,\n",
    "                                                                 cv=5))\n",
    "        #model = make_pipeline(PolynomialFeatures(degree), LassoCV(eps=lasso_eps,n_alphas=lasso_nalpha, \n",
    "                                                                  #max_iter=lasso_iter,normalize=True,cv=5))\n",
    "        #model = make_pipeline(PolynomialFeatures(degree), LinearRegression(normalize=True))\n",
    "        model.fit(X_train, y_train)\n",
    "        y_pred = np.array(model.predict(X_train))\n",
    "        test_pred = np.array(model.predict(X_test))\n",
    "        RMSE=np.sqrt(np.sum(np.square(y_pred-y_train)))\n",
    "        test_score = model.score(X_test,y_test)\n",
    "        random_sample_score.append(test_score)\n",
    "        poly_degree.append(degree)\n",
    "    \n",
    "    var_random.append(np.std(np.array(random_sample_score)))\n",
    "    mean_random.append(np.mean(np.array(random_sample_score)))\n",
    "\n",
    "    df_score = pd.DataFrame(data={'degree':[d for d in range(degree_min,degree_max+1)],\n",
    "                                  'Linear sample score':linear_sample_score,\n",
    "                                  'Random sample score':random_sample_score})\n",
    "    dfs.append(df_score)\n",
    "    #print(df_score)\n",
    "    #print(\"\\n\")\n",
    "    print (\"Run # {} finished\".format(i+1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "max_var = max(np.max(var_linear),np.max(var_random))\n",
    "min_mean = min(np.min(mean_linear),np.min(mean_random))\n",
    "\n",
    "plt.figure()\n",
    "plt.xlim((0.0,max_var+0.05))\n",
    "plt.ylim((0.0,max_var+0.05))\n",
    "plt.xlabel(\"Variation of linearly sampled score\")\n",
    "plt.ylabel(\"Variation of randomly sampled score\")\n",
    "plt.scatter(var_linear,var_random)\n",
    "\n",
    "plt.figure()\n",
    "plt.xlim((min_mean-0.05,1.0))\n",
    "plt.ylim((min_mean-0.05,1.0))\n",
    "plt.xlabel(\"Mean of linearly sampled score\")\n",
    "plt.ylabel(\"Mean of randomly sampled score\")\n",
    "plt.scatter(mean_linear,mean_random)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "df1=pd.concat(dfs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x213cd0da9b0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rand = []\n",
    "lin = []\n",
    "for i in range(degree_max+1-degree_min):\n",
    "    rand.append(df1.loc[i]['Random sample score'].mean())\n",
    "    lin.append(df1.loc[i]['Linear sample score'].mean())\n",
    "\n",
    "plt.figure(figsize=(8,5))\n",
    "plt.plot(range(degree_min, degree_max+1),lin)\n",
    "plt.plot(range(degree_min, degree_max+1),rand)\n",
    "plt.xlabel(\"Model complexity (degree of polynomial)\")\n",
    "plt.ylabel(\"Model score on test set\")\n",
    "plt.legend(['Linear sampling method','Random sampling method'])\n",
    "plt.grid(True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
